#include "platform.h"
#include "grftreenode.h"
#include "grfnode.h"
#define GRF_TREE_HASH_TABLE_SIZE 32


/// Note: root == GrfTreeNode(true, NULL, NULL, NULL)
GrfTreeNode::GrfTreeNode(bool isdir, char* name, GrfNode* ptr, GrfTreeNode* parent)
{
	m_name = name;
	m_subdir = ( isdir ) ? new HashTable<GrfTreeNode>(GRF_TREE_HASH_TABLE_SIZE) : NULL;
	m_ptr = ptr;
	m_parent = parent;
}


GrfTreeNode::~GrfTreeNode(void)
{
	delete m_subdir;
}


size_t GrfTreeNode::grf_tree_list_node(GrfTreeNode** arr, size_t num)
{
	if( m_subdir == NULL )
	{// not a directory, behave as if empty
		memset(arr, NULL, num * sizeof(arr[0]));
		return 0;
	}

	return m_subdir->foreach_val(arr, num);
}


bool GrfTreeNode::isdir(void) const
{
	return ( m_subdir != NULL );
}


const char* GrfTreeNode::name(void)
{
	return m_name.c_str();
}


uint32_t GrfTreeNode::count(void)
{
	if( m_subdir == NULL )
		return 0;

	return m_subdir->count();
}


GrfTreeNode* GrfTreeNode::parent(void)
{
	return m_parent;
}


GrfNode* GrfTreeNode::file(void)
{
	return m_ptr;
}


void GrfTreeNode::prv_grf_reg_tree_node(GrfNode* cur_node)
{
	const char* fn = cur_node->filename();
	char dirname[4096];
	GrfTreeNode* parent = this;
	GrfTreeNode* newnode;

	while( 1 )
	{
		size_t pos;
		// locate either / or \ in filename...
		for(pos=0;(*(fn+pos)!=0) && (*(fn+pos)!='/') && (*(fn+pos)!='\\');pos++);
		memcpy(&dirname, fn, pos+1);
		if (*(fn+pos)==0) break; // record file~

		// this is a directory, check if already existing...
		dirname[pos] = 0;
		fn+=pos+1;

		newnode = parent->m_subdir->find(dirname);
		if( newnode != NULL )
		{// found it !
			if( !newnode->isdir() )
			{
				// bogus grf file: directory with same name as a file... convert to directory !
				newnode->m_subdir = new HashTable<GrfTreeNode>(GRF_TREE_HASH_TABLE_SIZE);
			}
		}
		else
		{// not found -> create a new node
			newnode = new GrfTreeNode(true, dirname, NULL, parent);
			parent->m_subdir->insert(dirname, newnode);
		}

		parent = newnode;
	}

	// record file
	newnode = new GrfTreeNode(false, dirname, cur_node, parent);
	cur_node->tree_parent = newnode;
	parent->m_subdir->insert(dirname, newnode);
}
